package com.galacticconversion.util;

import com.galacticconversion.model.DataStorage;

import java.util.HashMap;
import java.util.Map;

/**
 * 罗马数字处理工具类
 */
public class RomanNumberUtil {
    private static final Map<Character, Integer> ROMAN_VALUES;

    static {
        ROMAN_VALUES = new HashMap<>();
        ROMAN_VALUES.put('I', 1);
        ROMAN_VALUES.put('V', 5);
        ROMAN_VALUES.put('X', 10);
        ROMAN_VALUES.put('L', 50);
        ROMAN_VALUES.put('C', 100);
        ROMAN_VALUES.put('D', 500);
        ROMAN_VALUES.put('M', 1000);
    }

    /**
     * 将罗马数字转换为十进制数
     */
    public static int romanToDecimal(String roman) {
        if (roman == null || roman.isEmpty() || !isValidRoman(roman)) {
            return -1;
        }

        int total = 0;
        int prevValue = 0;

        // 从右向左解析
        for (int i = roman.length() - 1; i >= 0; i--) {
            int currentValue = ROMAN_VALUES.get(roman.charAt(i));

            if (currentValue < prevValue) {
                total -= currentValue;
            } else {
                total += currentValue;
            }
            prevValue = currentValue;
        }
        return total;
    }

    /**
     * 验证罗马数字合法性
     */
    public static boolean isValidRoman(String roman) {
        // 检查无效字符
        for (char c : roman.toCharArray()) {
            if (!ROMAN_VALUES.containsKey(c)) {
                return false;
            }
        }

        // 检查重复规则
        if (roman.matches(".*(D|V|L).*\\1.*")) { // D、V、L 不能重复
            return false;
        }
        if (roman.matches(".*(I|X|C|M)\\1{3,}.*")) { // I、X、C、M 最多连续3次
            return false;
        }

        // 检查减法规则
        if (roman.matches(".*I[L|C|D|M].*") || // I只能在V或X前
                roman.matches(".*X[D|M].*") ||     // X只能在L或C前
                roman.matches(".*V.*[I|X].*") ||   // V不能被减
                roman.matches(".*L.*[X|C].*") ||   // L不能被减
                roman.matches(".*D.*[C|M].*")) {   // D不能被减
            return false;
        }

        return true;
    }

    public static String convertGalacticToRoman(String galacticUnits, DataStorage dataStorage) {
        if (galacticUnits.isEmpty()) return "";

        StringBuilder roman = new StringBuilder();
        for (String unit : galacticUnits.split(" ")) {
            if (!dataStorage.getGalacticToRoman().containsKey(unit)) {
                return "";
            }
            roman.append(dataStorage.getGalacticToRoman().get(unit));
        }
        return roman.toString();
    }
}
